import {
  VuexModule,
  Module,
  getModule,
  Mutation,
  Action
} from 'vuex-module-decorators'
import route from '@/core/router'
import store from '@/store'
import { _set } from '@/utils/storage'
import { cloneDeep } from 'lodash-es'
import { commonServices } from '@/common/services/common';
import { asyncRouterMap } from '@/routes'
import { GlobalLayout } from '@/layouts'
import { IPower } from '@/common/services/power';
import { RouteConfig } from 'vue-router'
import { formatTree } from '@/utils/tools';
import { MenuTypeEnum } from '@/common/enum'
import { userModule, PROJECT_TYPE } from './user'

export interface IPermissionState {
  menuData: RouteOptions[]
  authData: any[]
  allAuthData: any[]
}

export type RouteOptions = RouteConfig & {
  hidden?: boolean
}

export type IMenu = RouteOptions & {
  id?: string,
  pid?: string,
  invisible?: boolean
}

// 大户私有化菜单
export const LARGE_URLS = [
  '/member/large-grain'
]
// 一般农户私有化菜单
export const NORMAL_URLS = [
  '/member/list',
  '/member/death',
  '/member/farmers',
  '/member/grain'
]

// 种植粮食一次性补贴菜单
export const PLANT_URLS = [
  '/member/plant',
]

function generateRouter(data: IPower[]): IMenu[] {
  let indexRouter: IMenu[] = [
    {
      path: '/',
      name: 'index',
      component: GlobalLayout,
      meta: { title: '主页' },
      redirect: '/common',
      children: [
        ...generateChildRouters(data),
      ]
    },
    {
      "path": "*", "redirect": "/404", "hidden": true
    },
  ]
  return indexRouter;
}

function generateChildRouters(data: IPower[]): IMenu[] {
  let routes: IMenu[] = [];
  const asyncRoutes = asyncRouterMap.find(route => route.path === '/')
  if (asyncRoutes && asyncRoutes.children) {
    // @todo
    // 获取按钮权限 1、是菜单 2是按钮
    const permissions = data.filter(item => +item.is_menu === MenuTypeEnum.BUTTON)
    // 菜单组
    const menus = data.filter(item => +item.is_menu === MenuTypeEnum.MENU)
    // 组装权限
    let hashMap: Record<string, Array<{ label: string; value: string }>> = {}
    permissions.forEach(permission => {
      if (!hashMap[permission.power_up_id]) {
        hashMap[permission.power_up_id] = []
      }
      hashMap[permission.power_up_id].push({
        value: permission.key,
        label: permission.power_nam
      })
    })
    menus.forEach(menu => {
      // @ts-ignore
      menu.meta = {}
      if (hashMap[menu.power_id]) {
        // @ts-ignore
        menu.meta.permission = hashMap[menu.power_id]
      }
      // @todo
      // 项目私有化
      if (LARGE_URLS.includes(menu.power_web_url)) {
        // @ts-ignore
        menu.meta.projects = [PROJECT_TYPE.LARGE]
      }
      if (NORMAL_URLS.includes(menu.power_web_url)) {
        // @ts-ignore
        menu.meta.projects = [PROJECT_TYPE.NORMAL]
      }
      if (PLANT_URLS.includes(menu.power_web_url)) {
        // @ts-ignore
        menu.meta.projects = [PROJECT_TYPE.PLANT]
      }
    })
    // @ts-ignore
    routes = menus.map(route => {
      const matchedRoute = matchRoute(route.power_web_url, asyncRoutes.children)
      if (matchedRoute) {
        delete matchedRoute.children
        return {
          ...matchedRoute,
          id: route.power_id,
          pid: route.power_up_id,
          _name: route.power_nam,
          meta: {
            ...matchedRoute.meta,
            title: route.power_nam,
            // @ts-ignore
            permission: route.meta ? route.meta.permission : [],
            // @ts-ignore
            projects: route.meta.projects ? route.meta.projects : []
          }
        }
      } else {
        return {
          id: route.power_id,
          pid: route.power_up_id,
          path: route.power_web_url || '',
          name: route.power_web_url,
          _name: route.power_nam,
          component: null,
          meta: {
            title: route.power_nam,
            icon: false,
            // @ts-ignore
            permission: route.meta ? route.meta.permission : [],
            // @ts-ignore
            projects: route.meta.projects ? route.meta.projects : []
          }
        }
      }
    })
  }

  return formatTree(routes, { id: 'id', parentId: 'pid' });
}

function matchRoute(path: string, routes: IMenu[]): IMenu | undefined {
  let currentRoute: IMenu | undefined = undefined;
  for (let i = 0; i < routes.length; i++) {
    const route = routes[i];
    if (route.path === path) {
      currentRoute = route;
      break;
    } else if (route.children && route.children.length) {
      currentRoute = matchRoute(path, route.children)
      if (currentRoute) break;
    }
  }
  return currentRoute ? {
    ...currentRoute
  } : undefined;
}

@Module({
  dynamic: true,
  namespaced: true,
  store,
  name: 'permission',
})
class Permission extends VuexModule implements IPermissionState {
  // 菜单数据
  public menuData: RouteOptions[] = []

  // 路由数据
  public dynamicRoutes: RouteConfig[] = []

  // 授权数据
  public authData: any[] = []

  // 所有授权数据
  public allAuthData: any[] = []

  // @todo
  // 针对不同项目类型过滤菜单
  get filteredMenu() {
    const tag = userModule.currentProject.task_usr_tab
    if (!tag) return this.menuData
    const mapNext = (data: RouteOptions[]) => {
      return data.filter(menu => {
        if (menu.meta && menu.meta.projects && menu.meta.projects.length) {
          return menu.meta.projects.includes(tag)
        } else if (menu.children && menu.children.length) {
          menu.children = mapNext(menu.children)
        }
        return true
      })
    }
    const menus = mapNext(cloneDeep(this.menuData))
    return menus
  }

  // 独立判断是否具有帮助文档权限已用于全局控制编辑按钮
  get isEditHelper() {
    return this.allAuthData.findIndex(item => item.key === 'document.edit') !== -1
  }

  /**
   * 更新用户可访问菜单
   *
   * @param {*} menuData
   * @memberof Permission
   */
  @Mutation
  public SET_PERMISSIONLIST(menuData: IMenu[]) {
    this.menuData = menuData
  }

  /**
   * 设置路由
   *
   * @param {RouteConfig[]} routes
   * @memberof Permission
   */
  @Mutation
  public SET_ROUTES(routes: RouteOptions[]) {
    // 根据菜单数据生成路由表
    this.dynamicRoutes = routes
    route.addRoutes(this.dynamicRoutes)
  }

  /**
   * 更新授权数据
   *
   * @param {*} authData
   * @memberof Permission
   */
  @Mutation
  public SET_AUTH_DATA(authData: any[]) {
    // this.authData = authData
    // _set('authData', authData, 's')
  }

  /**
   * 更新所有授权数据
   *
   * @param {*} allAuthData
   * @memberof Permission
   */
  @Mutation
  public SET_ALL_AUTH_DATA(allAuthData: any[]) {
    this.allAuthData = allAuthData
    // _set('allAuthData', allAuthData, 's')
  }

  /**
   * 清空数据
   *
   * @memberof Permission
   */
  @Mutation
  public CLEAR_PERMISSION() {
    // this.menuData = []
    // this.dynamicRoutes = []
    // this.authData = []
    // this.allAuthData = []
  }

  /**
   * 获取用户权限相关数据
   *
   * @memberof Permission
   */
  @Action
  public async getPermissionList() {
    try {
      let { data } = await commonServices.getMenu();
      this.SET_ALL_AUTH_DATA(data.filter(item => +item.is_menu === MenuTypeEnum.BUTTON))
      // 获取用户能访问的菜单
      if (data && data.length) {
        let routes = generateRouter(data)
        console.log('routes =>', routes)
        this.SET_ROUTES(routes)
        // @ts-ignore
        this.SET_PERMISSIONLIST(routes[0].children)
      }
    } catch (err) {
      console.log(err)
    }

    // if (result.auth && result.auth.length) {
    //   this.SET_AUTH_DATA(result.auth)
    // }
    // if (result.allAuth && result.allAuth.length) {
    //   this.SET_ALL_AUTH_DATA(result.allAuth)
    // }
    // return menuData
  }
}

export const permission = getModule(Permission)

export default Permission
